package com.bytic.miaosha.service.impl;

import com.bytic.miaosha.business.MiaoshaBusiness;
import com.bytic.miaosha.constant.StatusConstant;
import com.bytic.miaosha.domain.MiaoshaOrder;
import com.bytic.miaosha.domain.MiaoshaUser;
import com.bytic.miaosha.domain.OrderInfo;
import com.bytic.miaosha.redis.MiaoshaKey;
import com.bytic.miaosha.service.GoodsService;
import com.bytic.miaosha.service.MiaoshaService;
import com.bytic.miaosha.service.OrderService;
import com.bytic.miaosha.service.RedisService;
import com.bytic.miaosha.utils.MD5Utils;
import com.bytic.miaosha.utils.UUIDUtils;
import com.bytic.miaosha.vo.GoodsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 推荐规则：
 *      自身 service 中只注入自身的 dao，如果想注入其他的 dao，最好注入其他的service，然后再注入的service中引入其自身的dao
 */
@Service
public class MiaoshaServiceImpl implements MiaoshaService {

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RedisService redisService;

    @Override
    @Transactional
    public OrderInfo miaosha(MiaoshaUser user, GoodsVO goods) {
        // 减库存 下订单 写入秒杀订单
        boolean result = goodsService.reduceStock(goods.getId());
        if (result) {
            return orderService.createOrder(user, goods);
        } else {
            setMiaoshaOver(goods.getId()); // 秒杀结束
            return null;
        }
    }

    @Override
    public long getMiaoshaResult(long userId, long goodsId) {
        MiaoshaOrder miaoshaOrder = orderService.getMiaoshaOrderByUserIdGoodsId(userId, goodsId);
        if (miaoshaOrder != null) {
            return miaoshaOrder.getOrderId();
        }
        boolean isOver = getMiaoshaOVer(goodsId);
        if (isOver) {
            return StatusConstant.MIAOSHA_FAIL;
        } else {
            return StatusConstant.QUEUING;
        }
    }

    private boolean getMiaoshaOVer(long goodsId) {
        return redisService.exists(MiaoshaKey.goodsOver, "" + goodsId);
    }

    private void setMiaoshaOver(Long goodsId) {
        redisService.set(MiaoshaKey.goodsOver, "" + goodsId, true);
    }

    @Override
    public String createMiaoshaPath(MiaoshaUser user, long goodsId) {
        if (user == null || goodsId <= 0) {
            return null;
        }
        String path = MD5Utils.md5(UUIDUtils.uuid() + "123456");
        redisService.set(MiaoshaKey.miaoshaPath, "" + user.getId() + "_" + goodsId, path);
        return path;
    }

    @Override
    public boolean checkMiaoshaPath(MiaoshaUser user, long goodsId, String path) {
        if (user == null || StringUtils.isEmpty(path)) {
            return false;
        }
        String result = redisService.get(MiaoshaKey.miaoshaPath, "" + user.getId() + "_" + goodsId, String.class);
        return path.equals(result);
    }

    @Override
    public BufferedImage createVerifyCode(MiaoshaUser user, long goodsId) {
        if (user == null || goodsId <= 0) {
            return null;
        }
        int width = 80;
        int height = 32;
        //create the image
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        // set the background color
        g.setColor(new Color(0xDCDCDC));
        g.fillRect(0, 0, width, height);
        // draw the border
        g.setColor(Color.black);
        g.drawRect(0, 0, width - 1, height - 1);
        // create a random instance to generate the codes
        Random rdm = new Random();
        // make some confusion
        for (int i = 0; i < 50; i++) {
            int x = rdm.nextInt(width);
            int y = rdm.nextInt(height);
            g.drawOval(x, y, 0, 0);
        }
        // generate a random code
        String verifyCode = MiaoshaBusiness.generateVerifyCode(rdm);
        g.setColor(new Color(0, 100, 0));
        g.setFont(new Font("Candara", Font.BOLD, 24));
        g.drawString(verifyCode, 8, 24);
        g.dispose();
        //把验证码存到redis中
        int rnd = MiaoshaBusiness.calc(verifyCode);

        redisService.set(MiaoshaKey.miaoshaVerifyCode, user.getId() + "_" + goodsId, rnd);
        return image;
    }

    @Override
    public boolean checkVerifyCode(MiaoshaUser user, long goodsId, int verifyCode) {
        if (user == null || goodsId <= 0) {
            return false;
        }
        Integer code = redisService.get(MiaoshaKey.miaoshaVerifyCode, user.getId() + "_" + goodsId, Integer.class);
        if (code == null || verifyCode - code != 0) {
            return false;
        }
        redisService.decr(MiaoshaKey.miaoshaVerifyCode, user.getId() + "_" + goodsId);
        return true;
    }
}
